﻿using System;
using System.Collections;
using System.Data;

namespace BrandonHaynes.Data
	{
	public class ReflectedDataReaderAdapter : IDataReader
		{
		private IEnumerable Adaptees { get; set; }
		private IEnumerator Enumerator { get; set; }
		private IDataRecord Current { get; set; }

		public ReflectedDataReaderAdapter(IEnumerable adaptees)
			{
			Adaptees = adaptees;
			Enumerator = Adaptees.GetEnumerator();
			}

		#region IDataReader Members

		public void Close()
			{ Adaptees = null; }

		public int Depth { get; set; }

		public DataTable GetSchemaTable()
			{ return null; }

		public bool IsClosed 
			{ get { return Adaptees == null; } }

		public bool NextResult()
			{ return false; }

		public bool Read()
			{ 
			if(Enumerator.MoveNext())
				{
				Current = new ReflectedDataRecordAdapter(Enumerator.Current);
				return true;
				}

			return false;
			}

		public int RecordsAffected
			{ get { return 0; } }

		#endregion

		#region IDisposable Members

		public void Dispose()
			{
			Dispose(true);
			GC.SuppressFinalize(this); 
			}

	   protected virtual void Dispose(bool disposing) 
			{
			if (disposing) 
				{
				var disposable = Adaptees as IDisposable;

				if (disposable != null)
					disposable.Dispose();
				}

			Adaptees = null;
			}

		#endregion

		#region IDataRecord Members

		public int FieldCount
			{ get { return Current.FieldCount; } }

		public bool GetBoolean(int i)
		{ return Current.GetBoolean(i); }

		public byte GetByte(int i)
		{ return Current.GetByte(i); }

		public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
			{ return Current.GetBytes(i, fieldOffset, buffer, bufferoffset, length); }

		public char GetChar(int i)
			{ return Current.GetChar(i); }

		public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
			{ return Current.GetChars(i, fieldoffset, buffer, bufferoffset, length); }

		public IDataReader GetData(int i)
			{ return Current.GetData(i); }

		public string GetDataTypeName(int i)
			{ return Current.GetDataTypeName(i); }

		public DateTime GetDateTime(int i)
		{ return Current.GetDateTime(i); }

		public decimal GetDecimal(int i)
		{ return Current.GetDecimal(i); }

		public double GetDouble(int i)
		{ return Current.GetDouble(i); }

		public Type GetFieldType(int i)
		{ return Current.GetFieldType(i); }

		public float GetFloat(int i)
			{ return Current.GetFloat(i); }

		public Guid GetGuid(int i)
			{ return Current.GetGuid(i); }

		public short GetInt16(int i)
			{ return Current.GetInt16(i); }

		public int GetInt32(int i)
			{ return Current.GetInt32(i); }

		public long GetInt64(int i)
			{ return Current.GetInt64(i); }

		public string GetName(int i)
			{ return Current.GetName(i); }

		public int GetOrdinal(string name)
			{ return Current.GetOrdinal(name); }

		public string GetString(int i)
			{ return Current.GetString(i); }

		public object GetValue(int i)
			{ return Current.GetValue(i); }

		public int GetValues(object[] values)
			{ return Current.GetValues(values); }

		public bool IsDBNull(int i)
			{ return Current.IsDBNull(i); }

		public object this[string name]
			{ get { return Current[name]; } }

		public object this[int i]
			{ get { return Current[i]; } }

		#endregion
		}
	}
